home *** CD-ROM | disk | FTP | other *** search
- /* $Revision Header *** Header built automatically - do not edit! ***********
- *
- * (C) Copyright 1991 by Torsten Jürgeleit
- *
- * Name .....: files.c
- * Created ..: Thursday 19-Dec-91 20:00:48
- * Revision .: 0
- *
- * Date Author Comment
- * ========= ==================== ====================
- * 11-Apr-92 Torsten Jürgeleit corrected abort if line too long
- * 19-Dec-91 Torsten Jürgeleit Created this file!
- *
- ****************************************************************************
- *
- * Support routines for reading and parsing text files
- *
- * $Revision Header ********************************************************/
-
- /* Includes */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <libraries/dos.h>
- #include <libraries/diskfont.h>
- #include <intuition/intuition.h>
- #ifdef AZTEC_C
- #include <functions.h> /* needed for Aztec C - prototypes and pragmas for all Amiga system functions */
- #endif
- #include <libraries/memwatch.h> /* header file for memory debug link library (Fish 240) - AFTER functions.h */
- #include <string.h>
- #include "/render/render.h"
- #include "files.h"
-
- /* Defines for internal flags */
-
- #define TEXT_FILE_FLAG_READ_NEXT_LINE (1 << 15) /* if current line is empty or continued then read next line too */
-
- /* Static prototypes */
-
- SHORT fill_read_buffer(struct FileData *fd);
- BPTR dos_open(BYTE *name, LONG flags);
- LONG dos_read(BPTR fh, BYTE *buffer, LONG size);
- VOID dos_close(BPTR fh);
-
- /* Static pragmas */
-
- #pragma regcall(fill_read_buffer(a0))
- #pragma regcall(dos_open(a0,d0))
- #pragma regcall(dos_read(a0,a1,d0))
- #pragma regcall(dos_close(a0))
-
- /* Open text file */
-
- struct FileData *
- open_text_file(BYTE *name, USHORT read_buffer_size, USHORT line_buffer_size,
- USHORT flags)
- {
- struct FileData *fd = NULL;
-
- if (name && read_buffer_size && line_buffer_size) {
- BPTR fh;
-
- if (fh = dos_open(name, (LONG)MODE_OLDFILE)) {
- if (!(fd = AllocMem((LONG)(sizeof(struct FileData) +
- read_buffer_size + line_buffer_size + 1),
- (LONG)MEMF_PUBLIC))) {
- dos_close(fh);
- } else {
-
- /* Init internal file data */
- fd->fd_Name = name;
- fd->fd_ReadBufferSize = read_buffer_size;
- fd->fd_LineBufferSize = line_buffer_size;
- fd->fd_Flags = flags;
- fd->fd_FileHandle = fh;
- fd->fd_ReadBuffer = (BYTE *)(fd + 1);
- fd->fd_CurrentPtr = NULL;
- fd->fd_LineBuffer = fd->fd_ReadBuffer + read_buffer_size;
- fd->fd_ID = ISUP_ID;
-
- /* Init public file data struct */
- fd->fd_Line = NULL;
- fd->fd_LineLen = 0;
- fd->fd_LineNum = 0;
- }
- }
- }
- return(fd);
- }
- /* Read line from text file */
-
- SHORT
- read_text_line(struct FileData *fd)
- {
- SHORT status = TEXT_FILE_STATUS_NORMAL;
-
- if (!fd || fd->fd_ID != ISUP_ID) {
- status = TEXT_FILE_ERROR_NO_FILE_DATA;
- } else {
- BYTE *line = fd->fd_LineBuffer;
- USHORT flags = fd->fd_Flags, len = 0;
-
- do {
- BYTE c, *ptr;
-
- /* Fill read buffer */
- if (!(ptr = fd->fd_CurrentPtr) || ptr >= fd->fd_EndPtr) {
- if ((status = fill_read_buffer(fd)) == TEXT_FILE_STATUS_NORMAL) {
- ptr = fd->fd_CurrentPtr;
- }
- }
- if (status == TEXT_FILE_STATUS_NORMAL) {
-
- /* Strip leading white space */
- if (flags & TEXT_FILE_FLAG_TRIM_LINE) {
- while ((c = *ptr) == ' ' || c == '\t') {
- if (++ptr >= fd->fd_EndPtr) {
- if ((status = fill_read_buffer(fd)) !=
- TEXT_FILE_STATUS_NORMAL) {
- break;
- } else {
- ptr = fd->fd_CurrentPtr;
- }
- }
- }
- }
- if (status == TEXT_FILE_STATUS_NORMAL) {
-
- /* Copy line from read buffer to line buffer */
- if (flags & TEXT_FILE_FLAG_SKIP_COMMENTS) {
- BOOL comment = FALSE;
-
- /* Copy without comments */
- while ((c = *ptr) != '\n' || comment == TRUE) {
-
- /* Write char to line buffer */
- if (comment == FALSE) {
- if (len >= fd->fd_LineBufferSize) {
- status = TEXT_FILE_ERROR_LINE_TOO_LONG;
- break;
- } else {
- *line++ = c;
- len++;
- }
- }
-
- /* Increment ptr and fill read buffer if neccessary */
- if (++ptr == fd->fd_EndPtr) {
- if ((status = fill_read_buffer(fd)) !=
- TEXT_FILE_STATUS_NORMAL) {
- break;
- } else {
- ptr = fd->fd_CurrentPtr;
- }
- }
-
- /* Check for comment delimiters */
- if (comment == FALSE) {
- if (c == '/' && *ptr == '*') {
- comment = TRUE;
-
- /* Remove '/' from line */
- line--;
- len--;
- }
- } else {
- if (c == '\n') {
- fd->fd_LineNum++;
- } else {
- if (c == '*' && *ptr == '/') {
- comment = FALSE;
-
- /* Skip '/' */
- if (++ptr == fd->fd_EndPtr) {
- if ((status = fill_read_buffer(fd)) !=
- TEXT_FILE_STATUS_NORMAL) {
- break;
- } else {
- ptr = fd->fd_CurrentPtr;
- }
- }
- }
- }
- }
- }
- } else {
-
- /* Copy with comments */
- while ((c = *ptr) != '\n') {
-
- /* Write char to line buffer */
- if (len >= fd->fd_LineBufferSize) {
- status = TEXT_FILE_ERROR_LINE_TOO_LONG;
- break;
- } else {
- *line++ = c;
- len++;
-
- /* Increment ptr and fill read buffer if neccessary */
- if (++ptr == fd->fd_EndPtr) {
- if ((status = fill_read_buffer(fd)) !=
- TEXT_FILE_STATUS_NORMAL) {
- break;
- } else {
- ptr = fd->fd_CurrentPtr;
- }
- }
- }
- }
- }
- if (status == TEXT_FILE_STATUS_NORMAL) {
-
- /* Strip trailing white space */
- if (flags & TEXT_FILE_FLAG_TRIM_LINE) {
- while (len && ((c = *(line - 1)) == ' ' || c == '\t')) {
- line--;
- len--;
- }
- }
- if (!len) {
-
- /* Check for skip empty line */
- if (flags & TEXT_FILE_FLAG_SKIP_EMPTY_LINES) {
- flags |= TEXT_FILE_FLAG_READ_NEXT_LINE;
- } else {
- flags &= ~TEXT_FILE_FLAG_READ_NEXT_LINE;
- }
- } else {
-
- /* Check for line continuation - last char is '\'? */
- if (flags & TEXT_FILE_FLAG_LINE_CONTINUATION) {
- if (*(line - 1) == '\\') {
- flags |= TEXT_FILE_FLAG_READ_NEXT_LINE;
-
- /* Strip '\' from end of line */
- line--;
- len--;
- } else {
- flags &= ~TEXT_FILE_FLAG_READ_NEXT_LINE;
- }
- } else {
- flags &= ~TEXT_FILE_FLAG_READ_NEXT_LINE;
- }
- }
-
- /* Mark end of string */
- *line = '\0';
- fd->fd_CurrentPtr = ptr + 1; /* skip trailing '\n' */
- fd->fd_LineNum++;
- }
- }
- }
- } while (status == TEXT_FILE_STATUS_NORMAL &&
- (flags & TEXT_FILE_FLAG_READ_NEXT_LINE));
- /* Init public data */
- if (status == TEXT_FILE_STATUS_NORMAL) {
- fd->fd_Line = fd->fd_LineBuffer;
- fd->fd_LineLen = len;
- } else {
- fd->fd_Line = NULL;
- fd->fd_LineLen = 0;
- }
- }
- return(status);
- }
- /* Fill read buffer from text file */
-
- STATIC SHORT
- fill_read_buffer(struct FileData *fd)
- {
- LONG len;
- SHORT status;
-
- if ((len = dos_read(fd->fd_FileHandle, fd->fd_ReadBuffer, (LONG)
- fd->fd_ReadBufferSize)) == -1L) {
- status = TEXT_FILE_ERROR_READ_FAILED;
- } else {
- if (!len) {
- status = TEXT_FILE_STATUS_EOF;
- } else {
- fd->fd_CurrentPtr = fd->fd_ReadBuffer;
- fd->fd_EndPtr = fd->fd_ReadBuffer + len;
- status = TEXT_FILE_STATUS_NORMAL;
- }
- }
- return(status);
- }
- /* Close text file */
-
- VOID
- close_text_file(struct FileData *fd)
- {
- if (fd && fd->fd_ID == ISUP_ID) {
- dos_close(fd->fd_FileHandle);
- FreeMem(fd, (LONG)(sizeof(struct FileData) + fd->fd_ReadBufferSize +
- fd->fd_LineBufferSize + 1));
- }
- }
- /* DOS calls between open and close of dos library
- * -> neccessary for DOS calls from within intuisup.library
- */
- #asm
- ;---------------------------------------------------------------------------
- ; Support macros
- ;---------------------------------------------------------------------------
-
- PUSH MACRO
- movem.l \1,-(sp)
- ENDM
-
- PULL MACRO
- movem.l (sp)+,\1
- ENDM
-
- CALLSYS MACRO
- XREF _LVO\1
- jsr _LVO\1(a6)
- ENDM
-
- ;---------------------------------------------------------------------------
- ; External definitions
- ;---------------------------------------------------------------------------
-
- XDEF _dos_open
- XDEF _dos_read
- XDEF _dos_close
-
- ;---------------------------------------------------------------------------
- ; BPTR dos_open(BYTE *name, LONG flags)
- ; a0 d0
- ;---------------------------------------------------------------------------
-
- _dos_open:
- PUSH d2-d3/a2/a6
-
- ; --- save parameters
- move.l a0,a2 ; a2 := file name ptr
- move.l d0,d2 ; d2 := flags
- moveq #0,d3 ; d3 := return code
-
- ; --- open dos library
- move.l (4).w,a6 ; a6 := SysBase
- lea dos_name(pc),a1 ; a1 := library name
- moveq #0,d0 ; d0 := version
- CALLSYS OpenLibrary
- tst.l d0
- beq.s do_exit
-
- ; --- call DOS function Open()
- move.l d0,a6 ; a6 := DosBase
- move.l a2,d1 ; d1 := file name ptr
- ; d2 := flags
- jsr -$1e(a6) ; CALLSYS Open -> Bug in c16.lib (POSITIVE lib offset)
- move.l d0,d3 ; d3 := BPTR to file handle
-
- ; --- close dos library
- move.l a6,a1 ; a1 := DosBase
- move.l (4).w,a6 ; a6 := SysBase
- CALLSYS CloseLibrary
-
- do_exit:
- ; --- prepare return code
- move.l d3,d0
-
- PULL d2-d3/a2/a6
- rts
-
- ;---------------------------------------------------------------------------
- ; LONG dos_read(BPTR fh, BYTE *buffer, LONG size);
- ; a0 a1 d0
- ;---------------------------------------------------------------------------
-
- _dos_read:
- PUSH d2-d4/a2-a3/a6
-
- ; --- save parameters
- move.l a0,a2 ; a2 := BPTR to file handle
- move.l a1,a3 ; a3 := buffer ptr
- move.l d0,d3 ; d3 := size
- moveq #-1,d4 ; d4 := return code
-
- ; --- open dos library
- move.l (4).w,a6 ; a6 := SysBase
- lea dos_name(pc),a1 ; a1 := library name
- moveq #0,d0 ; d0 := version
- CALLSYS OpenLibrary
- tst.l d0
- beq.s dr_exit
-
- ; --- call DOS function Read()
- move.l d0,a6 ; a6 := DosBase
- move.l a2,d1 ; d1 := BPTR to file handle
- move.l a3,d2 ; d2 := buffer ptr
- ; d3 := size
- jsr -$2a(a6) ; CALLSYS Read -> Bug in c16.lib (POSITIVE lib offset)
- move.l d0,d4 ; d4 := num of characters read
-
- ; --- close dos library
- move.l a6,a1 ; a1 := DosBase
- move.l (4).w,a6 ; a6 := SysBase
- CALLSYS CloseLibrary
-
- dr_exit:
- ; --- prepare return code
- move.l d4,d0
-
- PULL d2-d4/a2-a3/a6
- rts
-
- ;---------------------------------------------------------------------------
- ; VOID dos_close(BPTR fh);
- ; a0
- ;---------------------------------------------------------------------------
-
- _dos_close:
- PUSH a2/a6
-
- ; --- save parameters
- move.l a0,a2 ; a2 := BPTR to file handle
-
- ; --- open dos library
- move.l (4).w,a6 ; a6 := SysBase
- lea dos_name(pc),a1 ; a1 := library name
- moveq #0,d0 ; d0 := version
- CALLSYS OpenLibrary
- tst.l d0
- beq.s dc_exit
-
- ; --- call DOS function Close()
- move.l d0,a6 ; a6 := DosBase
- move.l a2,d1 ; d1 := BPTR to file handle
- jsr -$24(a6) ; CALLSYS Close -> Bug in c16.lib (POSITIVE lib offset)
-
- ; --- close dos library
- move.l a6,a1 ; a1 := DosBase
- move.l (4).w,a6 ; a6 := SysBase
- CALLSYS CloseLibrary
-
- dc_exit:
- PULL a2/a6
- rts
-
- ;---------------------------------------------------------------------------
- ; Static data
- ;---------------------------------------------------------------------------
-
- dos_name:
- dc.b "dos.library"
-
- EVEN
- #endasm
-